package cohesion.pools
{
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.utils.setInterval;
	import flash.utils.setTimeout;
	
	import flashx.textLayout.elements.BreakElement;
	
	import mx.utils.StringUtil;
	
	/**
	 * 对象池
	 * <p>
	 * 缓存一定数量的对象在其中，供反复使用。
	 * 会定期释放寄存时间过长的对象，默认的寄存时间为180秒，可以修改它。
	 * </p>
	 * @author 徐俊杰
	 * @date 2012-2-21
	 */
	public class ObjectPool
	{
		private var _maximum:uint = 30;
		
		private var _storageTime:Number = 180000;
		
		private var _objectClass:Class;
		
		/**
		 * 寄存的对象数组 
		 */		
		private var _objectsArray:Vector.<PoolObject>;
		
		/**
		 * 销毁触发器 
		 */		
		private var _destroyTimer:Timer;
		
		/**
		 * 实例化对象池 
		 * @param objectClass 寄存对象的类型
		 * 
		 */		
		public function ObjectPool(objectClass:Class)
		{
			_objectClass = objectClass;
			_objectsArray = new Vector.<PoolObject>();
		}
		
		/**
		 * 借取对象 
		 * @return objectClass类型的实例
		 * 
		 */		
		public function borrow():Object
		{
			if(_objectsArray == null || _objectsArray.length == 0)
			{
				return createInstance();
			}
			else
			{
				return _objectsArray.shift();
			}
		}
		
		/**
		 * 寄存对象
		 * 对象的类型和objectClass不符、池已填满，会导致寄存失败
		 * @param obj 寄存的对象
		 * @return 是否寄存成功
		 * 
		 */		
		public function storage(obj:Object):Boolean
		{
			if(!(obj is _objectClass))
			{
				throw new TypeError(StringUtil.substitute("{0}不是{1}类型的对象", obj, _objectClass));
				return false;
			}
			var result:Boolean = false;
			if(_objectsArray.length < _maximum)
			{
				_objectsArray.push(new PoolObject(obj, getTimer()));			//新寄存的对象放到最后
				result = true;
			}
			if(_objectsArray.length > 0)
			{
				if(_destroyTimer == null)
					createDestroyTimer();
				if(!_destroyTimer.running)
					_destroyTimer.start();
			}
			return result;
		}
			
		/**
		 * 创建销毁触发器 
		 * 
		 */		
		private function createDestroyTimer():void
		{
			_destroyTimer = new Timer(60000);
			_destroyTimer.addEventListener(TimerEvent.TIMER, destroyTimer_timerHandler);
		}
		
		protected function destroyTimer_timerHandler(event:TimerEvent):void
		{
			destroy();
			if(_objectsArray.length == 0)
				_destroyTimer.stop();
		}
		
		/**
		 * 创建objectClass的实例 
		 * @return objectClass类型的实例
		 * 
		 */		
		private function createInstance():Object
		{
			return new _objectClass;
		}
		
		/**
		 * 销毁可销毁的对象 
		 * 
		 */		
		private function destroy():void
		{
			var currentTime:Number = getTimer();
			for(var i:int = 0; i < _objectsArray.length; i++)			//因为新寄存的对象在后，旧对象在前，所以从前往后找
			{
				if(currentTime - _objectsArray[i].storageTime < _storageTime)
				{
					_objectsArray.splice(0, i + 1);
					break;
				}
			}
		}

		/**
		 * 寄存的对象的最大数量，设置此值会立即清理超出的对象
		 * @default 30
		 */
		public function get maximum():uint
		{
			return _maximum;
		}

		/**
		 * @private
		 */
		public function set maximum(value:uint):void
		{
			if(_maximum != value)
			{
				_maximum = value;
				if(_objectsArray.length > _maximum)
					_objectsArray.splice(0, _maximum - _objectsArray.length);
			}
			
		}

		/**
		 * 对象寄存的毫秒数；设置此值，并不会立即清理超出寄存时间的对象，需要等下次触发时才会清理。
		 * @default 180000毫秒（3分钟）
		 */
		public function get storageTime():Number
		{
			return _storageTime;
		}

		/**
		 * @private
		 */
		public function set storageTime(value:Number):void
		{
			if(_storageTime != value)
			{
				_storageTime = value;
			}
		}

		/**
		 * 寄存的对象类型
		 */
		public function get objectClass():Class
		{
			return _objectClass;
		}


	}
}